/* 
 * AUTHOR: Kevin Lam
 */

package com.apps.services;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.apps.datastore.dao.BookInformation;
import com.apps.services.FilterEnum.FilterOperatorType;
import com.apps.services.FilterEnum.FilterType;
import com.apps.services.SearchTypeEnum.SearchType;
import com.apps.ubc.cc.model.SaveonBookModel;
import com.apps.utils.BookSearchUtils;

class SearchTypeEnum {
	public enum SearchType {
		TITLE, AUTHOR, ISBN;
	}
}
class FilterEnum{
	public enum FilterType {
		TITLE, AUTHOR, ISBN, EDITION, INSTITUTE, DATE, COURSE, PRICE;
	}

	public enum FilterOperatorType {
		GREATER_THAN, LESS_THAN, EQUAL, NOT_EQUAL;
	}
	
}

public class SaveonbookService {

	public SaveonbookService() {
	}
	
	public List<SaveonBookModel> search(BookInformation bio){
		String optimizedTitle = getOptimizedTitle(bio);
		return titleSearch(optimizedTitle);
	}
	
	public List<SaveonBookModel> search(BookInformation bio, FilterType ft, String filterBy){
		String optimizedTitle = getOptimizedTitle(bio);
		 return filterBookList(titleSearch(optimizedTitle),ft,filterBy);
	}
	public BufferedReader getURLContentReader(String search, SearchType st)
			throws Exception {
		String query = search;
		if(search.contains("'"))
			query = query.substring(0,search.indexOf("'")); //SBK has bad SQL injection handling so must remove all characters in the title proceeding the ' symbol including the ' symbol itself.
		query = URLEncoder.encode(query,"UTF-8");
		String url = "";
		switch (st) {
		case TITLE:
			url = "http://saveonbook.com/search/title-search.jsp?title="
					+ query + "&active=0";
			break;
		case AUTHOR:
			url = "http://saveonbook.com/search/author-search.jsp?author="
					+ query + "&active=0";
			break;
		case ISBN:
			url = "http://saveonbook.com/search/ISBN-search.jsp?ISBN=" + query
					+ "&active=0";
			break;
		}
		return new BufferedReader(new InputStreamReader(
				new URL(url).openStream()));
	}
	
	public List<SaveonBookModel> filterBookList(List<SaveonBookModel> bol, FilterType ft, String value){
		List<SaveonBookModel> result = new ArrayList<SaveonBookModel>();
		for(Iterator i = bol.iterator(); i.hasNext();) {
			SaveonBookModel bo = (SaveonBookModel)i.next();
			String compare = "";
			switch(ft) {
			case TITLE:
				compare = bo.getTitle();
				break;
			case AUTHOR:
				compare = bo.getAuthor();
				break;
			case ISBN:
				compare = bo.getIsbn();
				break;
			case EDITION:
				compare = BookSearchUtils.parseEdition(bo.getEdition());
				break;
			case INSTITUTE:
				compare = bo.getInstitute();
				break;
			case DATE:
				compare = bo.getDate();
				break;
			case COURSE:
				compare = bo.getCourse();
				break;
			case PRICE:
				compare = bo.getPrice();
				break;
			}
			if (compare.toLowerCase().contains(value.toLowerCase()))
				result.add(bo);
		}
			
		return result;
	}
	
	public String getOptimizedTitle(BookInformation bio){
		String isbn = bio.getISBN();
		String author = bio.getAuthor();
		String title = bio.getTitle();
		List<SaveonBookModel> books = new ArrayList<SaveonBookModel>();
		String optimizedTitle = "";
		if (!isbn.isEmpty()) {
			try {

				books = parseURLContent(getURLContentReader(isbn,
						SearchType.ISBN));
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if(!author.isEmpty()){
			try {
				String[] authorlist= author.split("[^a-zA-Z0-9]");
				for(int i = 0; i < authorlist.length; i++) {
					books.addAll(parseURLContent(getURLContentReader(authorlist[i],
							SearchType.AUTHOR)));
				}
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (!books.isEmpty())
				optimizedTitle = BookSearchUtils.parseSearchableBookName(books,BookSearchUtils.findKeywords(title));
		}
		return optimizedTitle;
	}
	
	public List<SaveonBookModel> titleSearch(String title){
		List<SaveonBookModel> books = new ArrayList<SaveonBookModel>();
		try {
			books = parseURLContent(getURLContentReader(title, SearchType.TITLE));

		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return books;
			
	}
	
	public int[] getPriceRange(List<SaveonBookModel> bol){
		int[] range = new int[2];
		int min = 99999999;
		int max = 0;
		int tmp = 0;
		for(Iterator i = bol.iterator();i.hasNext();) {
			tmp = Integer.parseInt(((SaveonBookModel)i.next()).getPrice().replaceAll("[^\\d]", "").trim())/100;
			if (tmp > max)
				max = tmp;
			if (tmp < min)
				min = tmp;
		}
		if(max == 0)
			min = 0;
		range[0] = min;
		range[1] = max;
		return range;
	}

	public List<SaveonBookModel> parseURLContent(BufferedReader br) throws IOException {
		String line = br.readLine();
		List<SaveonBookModel> books = new ArrayList<SaveonBookModel>();
		while (line != null) {
			if (line.contains("<TR bgcolor=\"#E2E2E0\">")) {
				String title = "";
				String author = "";
				String edition = "";
				String isbn = "";
				String institute = "";
				String date = "";
				String course = "";
				String price = "";
				int foundCount = 0;
				while (line != null && foundCount < 7) {
					if (line.contains("<B>Title: </B>")) {
						title = line.substring(
								line.indexOf("<B>Title: </B>") + 14,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Author: </B>")) {
						author = line.substring(
								line.indexOf("<B>Author: </B>") + 15,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Edition: </B>")) {
						edition = line.substring(
								line.indexOf("<B>Edition: </B>") + 16,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Institute: </B>")) {
						institute = line.substring(
								line.indexOf("<B>Institute: </B>") + 18,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Course Nbr/Category: </B>")) {
						course = line
								.substring(
										line.indexOf("<B>Course Nbr/Category: </B>") + 27,
										line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Price: </B>")) {
						price = line.substring(
								line.indexOf("<B>Price: </B>") + 14,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>Advertised Date: </B>")) {
						date = line.substring(
								line.indexOf("<B>Advertised Date: </B>") + 24,
								line.indexOf("</TD>"));
						foundCount++;
					}
					if (line.contains("<B>ISBN: </B>")) {
						isbn = line.substring(
								line.indexOf("<B>ISBN: </B>") + 13,
								line.indexOf("</TD>"));
						foundCount++;
					}
					line = br.readLine();
				}
				SaveonBookModel bo = new SaveonBookModel(title, author, edition, isbn,
						institute, date, course, price);
				books.add(bo);
			}
			line = br.readLine();
		}

		// System.out.println(SearchUtils.parseSearchableBookName(books,
		// SearchUtils.findKeywords("Pkg Custom 4 Pc Multivariable Calculus 6/E + Ss Manual + Strategy for Integratio")));
		return books;
	}
}
